/*
 * 
 * 
 * 
 */
package com.hboxs.asl.controller.admin;

import com.hboxs.asl.FileInfo;
import com.hboxs.asl.Pageable;
import com.hboxs.asl.entity.*;
import com.hboxs.asl.service.*;
import com.hboxs.asl.util.PinYinUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

/**
 * Controller - 商品
 */
@Controller("adminProductController")
@RequestMapping("/asl-admin/product")
public class ProductController extends BaseController {

    @Resource(name = "productServiceImpl")
    private ProductService productService;
    @Resource(name = "productCategoryServiceImpl")
    private ProductCategoryService productCategoryService;
    @Resource(name = "goodsServiceImpl")
    private GoodsService goodsService;
    @Resource(name = "brandServiceImpl")
    private BrandService brandService;
    @Resource(name = "promotionServiceImpl")
    private PromotionService promotionService;
    @Resource(name = "tagServiceImpl")
    private TagService tagService;
    @Resource(name = "memberRankServiceImpl")
    private MemberRankService memberRankService;
    @Resource(name = "productImageServiceImpl")
    private ProductImageService productImageService;
    @Resource(name = "specificationServiceImpl")
    private SpecificationService specificationService;
    @Resource(name = "specificationValueServiceImpl")
    private SpecificationValueService specificationValueService;
    @Resource(name = "fileServiceImpl")
    private FileService fileService;
    @Resource(name = "shippingMethodServiceImpl")
    private ShippingMethodService shippingMethodService;

    /**
     * 检查编号是否唯一
     */
    @RequestMapping(value = "/check_sn", method = RequestMethod.GET)
    public
    @ResponseBody
    boolean checkSn(String previousSn, String sn) {
        if (StringUtils.isEmpty(sn)) {
            return false;
        }
        return productService.snUnique(previousSn, sn);
    }

    /**
     * 获取参数组
     */
    @RequestMapping(value = "/parameter_groups", method = RequestMethod.GET)
    public
    @ResponseBody
    Set<ParameterGroup> parameterGroups(Long id) {
        ProductCategory productCategory = productCategoryService.find(id);
        return productCategory.getParameterGroups();
    }

    /**
     * 获取属性
     */
    @RequestMapping(value = "/attributes", method = RequestMethod.GET)
    public
    @ResponseBody
    Set<Attribute> attributes(Long id) {
        ProductCategory productCategory = productCategoryService.find(id);
        return productCategory.getAttributes();
    }

    /**
     * 添加
     */
    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add(ModelMap model, HttpSession session, RedirectAttributes redirectAttributes) {

        if (shippingMethodService.findDefault() == null) {
            addFlashMessage(redirectAttributes, com.hboxs.asl.Message.error("请先添加一个默认的配送方式"));
            return "redirect:list.htm";
        }

        model.addAttribute("productCategoryTree", productCategoryService.findTree());
        model.addAttribute("brands", brandService.findAll());
        model.addAttribute("tags", tagService.findList(Tag.Type.product));
        model.addAttribute("memberRanks", memberRankService.findAll());
        model.addAttribute("specifications", specificationService.findAll());
        model.addAttribute("classifies", Product.Classify.values());
        session.setAttribute(IMAGE_TYPE, ProductImage.imageType.productImage);
        return "/admin/product/add";
    }

    /**
     * 保存
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public String save(Product product, Long productCategoryId, String classify, Long brandId, Long designerId, Long[] tagIds, Long[] specificationIds, HttpServletRequest request,
                       RedirectAttributes redirectAttributes, HttpSession session) {
        try {
            for (Iterator<ProductImage> iterator = product.getProductImages().iterator(); iterator.hasNext(); ) {
                ProductImage productImage = iterator.next();
                if (productImage == null || productImage.isEmpty()) {
                    iterator.remove();
                    continue;
                }
                if (productImage.getFile() != null && !productImage.getFile().isEmpty()) {
                    if (!fileService.isValid(FileInfo.FileType.image, productImage.getFile())) {
                        addFlashMessage(redirectAttributes, com.hboxs.asl.Message.error("admin.upload.invalid"));
                        return "redirect:add.htm";
                    }
                }
            }

            // 拼音分词
            String splitPinYin = PinYinUtils.getStringPinYin(product.getName());
            // 中文分词
            String splitName = PinYinUtils.getSplitWord(product.getName());
            product.setPinyin(splitPinYin);
            product.setKeyword(splitName);
            product.setProductCategory(productCategoryService.find(productCategoryId));
            product.setBrand(brandService.find(brandId));
            product.setTags(new HashSet<Tag>(tagService.findList(tagIds)));
            // seo 系统生成设置
            if (StringUtils.isEmpty(product.getSeoKeywords())) {
                product.setSeoKeywords(splitName);
            }
            if (StringUtils.isEmpty(product.getSeoDescription())) {
                product.setSeoDescription(com.hboxs.asl.Message.success("asl.index.title").toString());
            }
            if (StringUtils.isEmpty(product.getSeoTitle())) {
                product.setSeoTitle(com.hboxs.asl.Message.success("asl.index.title").toString());
            }
            if (StringUtils.isNotEmpty(product.getSn()) && productService.snExists(product.getSn())) {
                return ERROR_VIEW;
            }

            product.setPoint(new BigDecimal(0));
            product.setmPoint(new BigDecimal(0));

            product.setAllocatedStock(0);
            product.setHits(0L);
            product.setWeekHits(0L);
            product.setMonthHits(0L);
            product.setSales(product.getSales() == null ? 0L : product.getSales());
            product.setWeekSales(0L);
            product.setMonthSales(0L);
            product.setWeekHitsDate(new Date());
            product.setMonthHitsDate(new Date());
            product.setWeekSalesDate(new Date());
            product.setMonthSalesDate(new Date());
            product.setReviews(null);
            product.setConsultations(null);
            product.setFavoriteMembers(null);
            product.setPromotions(null);
            product.setCartItems(null);
            product.setOrderItems(null);
            product.setGiftItems(null);
            product.setProductNotifies(null);
            product.setIsMarketable(true);
            product.setIsTop(false);
            Product.Classify[] classifies = Product.Classify.values();
            for (MemberRank memberRank : memberRankService.findAll()) {
                String price = request.getParameter("memberPrice_" + memberRank.getId());
                if (StringUtils.isNotEmpty(price) && new BigDecimal(price).compareTo(new BigDecimal(0)) >= 0) {
                    product.getMemberPrice().put(memberRank, new BigDecimal(price));
                } else {
                    product.getMemberPrice().remove(memberRank);
                }
            }

            for (ProductImage productImage : product.getProductImages()) {
                productImageService.build(productImage, session.getAttribute(IMAGE_TYPE).toString());
            }
            Collections.sort(product.getProductImages());
            if (product.getImage() == null && product.getThumbnail() != null) {
                product.setImage(product.getThumbnail());
            }

            for (ParameterGroup parameterGroup : product.getProductCategory().getParameterGroups()) {
                for (Parameter parameter : parameterGroup.getParameters()) {
                    String parameterValue = request.getParameter("parameter_" + parameter.getId());
                    if (StringUtils.isNotEmpty(parameterValue)) {
                        product.getParameterValue().put(parameter, parameterValue);
                    } else {
                        product.getParameterValue().remove(parameter);
                    }
                }
            }

            for (Attribute attribute : product.getProductCategory().getAttributes()) {
                String[] attributeValues = request.getParameterValues("attribute_" + attribute.getId());
                String attributeValue = "";
                if (attributeValues != null) {
                    for (int i = 0; i < attributeValues.length; i++) {
                        attributeValue = attributeValue + "," + attributeValues[i];
                    }
                }
                if (StringUtils.isNotEmpty(attributeValue)) {
                    product.setAttributeValue(attribute, attributeValue);
                } else {
                    product.setAttributeValue(attribute, null);
                }
            }

            if (!isValid(product)) {
                return ERROR_VIEW;
            }

            Goods goods = new Goods();
            List<Product> products = new ArrayList<Product>();
            if (specificationIds != null && specificationIds.length > 0) {
                for (int i = 0; i < specificationIds.length; i++) {
                    Specification specification = specificationService.find(specificationIds[i]);
                    String[] specificationValueIds = request.getParameterValues("specification_" + specification.getId());
                    if (specificationValueIds != null && specificationValueIds.length > 0) {
                        for (int j = 0; j < specificationValueIds.length; j++) {
                            if (i == 0) {
                                if (j == 0) {
                                    product.setGoods(goods);
                                    product.setSpecifications(new HashSet<Specification>());
                                    product.setSpecificationValues(new HashSet<SpecificationValue>());
                                    products.add(product);
                                } else {
                                    Product specificationProduct = new Product();
                                    BeanUtils.copyProperties(product, specificationProduct);
                                    specificationProduct.setId(null);
                                    specificationProduct.setCreateDate(null);
                                    specificationProduct.setModifyDate(null);
                                    specificationProduct.setSn(null);
                                    specificationProduct.setAllocatedStock(0);
                                    specificationProduct.setHits(0L);
                                    specificationProduct.setWeekHits(0L);
                                    specificationProduct.setMonthHits(0L);
                                    specificationProduct.setSales(product.getSales() == null ? 0L : product.getSales());
                                    specificationProduct.setOrder(product.getOrder() == null ? 0 : product.getOrder());
                                    specificationProduct.setWeekSales(0L);
                                    specificationProduct.setMonthSales(0L);
                                    specificationProduct.setWeekHitsDate(new Date());
                                    specificationProduct.setMonthHitsDate(new Date());
                                    specificationProduct.setWeekSalesDate(new Date());
                                    specificationProduct.setMonthSalesDate(new Date());
                                    specificationProduct.setGoods(goods);
                                    specificationProduct.setReviews(null);
                                    specificationProduct.setConsultations(null);
                                    specificationProduct.setFavoriteMembers(null);
                                    specificationProduct.setSpecifications(new HashSet<Specification>());
                                    specificationProduct.setSpecificationValues(new HashSet<SpecificationValue>());
                                    specificationProduct.setPromotions(null);
                                    specificationProduct.setCartItems(null);
                                    specificationProduct.setOrderItems(null);
                                    specificationProduct.setGiftItems(null);
                                    specificationProduct.setProductNotifies(null);
                                    products.add(specificationProduct);
                                }
                            }
                            Product specificationProduct = products.get(j);
                            SpecificationValue specificationValue = specificationValueService.find(Long.valueOf(specificationValueIds[j]));
                            specificationProduct.getSpecifications().add(specification);
                            specificationProduct.getSpecificationValues().add(specificationValue);
                        }
                    }
                }
            } else {
                product.setGoods(goods);
                product.setSpecifications(null);
                product.setSpecificationValues(null);
                products.add(product);
            }
            goods.getProducts().clear();
            goods.getProducts().addAll(products);
            goodsService.save(goods);
            addFlashMessage(redirectAttributes, SUCCESS_MESSAGE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:list.htm";
    }

    /**
     * 编辑
     */
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Long id, ModelMap model, HttpSession session, RedirectAttributes redirectAttributes) {
        if (shippingMethodService.findDefault() == null) {
            addFlashMessage(redirectAttributes, com.hboxs.asl.Message.error("请先添加一个默认的配送方式"));
            return "redirect:list.htm";
        }
        model.addAttribute("productCategoryTree", productCategoryService.findTree());
        model.addAttribute("brands", brandService.findAll());
        model.addAttribute("tags", tagService.findList(Tag.Type.product));
        model.addAttribute("memberRanks", memberRankService.findAll());
        model.addAttribute("specifications", specificationService.findAll());
        model.addAttribute("product", productService.find(id));
        session.setAttribute(IMAGE_TYPE, ProductImage.imageType.productImage);
        Product product = productService.find(id);
        Set<Attribute> attributes = product.getProductCategory().getAttributes();
        return "/admin/product/edit";
    }

    /**
     * 更新
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String update(Product product, Long productCategoryId, Long brandId, Long designerId, Long[] tagIds, Long[] specificationIds, Long[] specificationProductIds, HttpServletRequest request,
                         RedirectAttributes redirectAttributes, HttpSession session) {
        try {
            for (Iterator<ProductImage> iterator = product.getProductImages().iterator(); iterator.hasNext(); ) {
                ProductImage productImage = iterator.next();
                if (productImage == null || productImage.isEmpty()) {
                    iterator.remove();
                    continue;
                }
                if (productImage.getFile() != null && !productImage.getFile().isEmpty()) {
                    if (!fileService.isValid(FileInfo.FileType.image, productImage.getFile())) {
                        addFlashMessage(redirectAttributes, com.hboxs.asl.Message.error("admin.upload.invalid"));
                        return "redirect:edit.htm?id=" + product.getId();
                    }
                }
            }

            Product pProduct = productService.find(product.getId());

            // 拼音分词
            String splitPinYin = PinYinUtils.getStringPinYin(product.getName());
            // 中文分词
            String splitName = PinYinUtils.getSplitWord(product.getName());

            product.setPinyin(splitPinYin);
            product.setKeyword(splitName);
            product.setProductCategory(productCategoryService.find(productCategoryId));
            product.setBrand(brandService.find(brandId));
            product.setTags(new HashSet<Tag>(tagService.findList(tagIds)));

            // seo 系统生成设置
            product.setSeoKeywords(splitName);
            product.setSeoDescription(com.hboxs.asl.Message.success("asl.index.title").toString());
            product.setSeoTitle(product.getName() + " - " + com.hboxs.asl.Message.success("asl.index.title").toString());


            if (pProduct == null) {
                return ERROR_VIEW;
            }
            if (StringUtils.isNotEmpty(product.getSn()) && !productService.snUnique(pProduct.getSn(), product.getSn())) {
                return ERROR_VIEW;
            }

            product.setPoint(new BigDecimal(0));
            product.setmPoint(new BigDecimal(0));

            for (ProductImage productImage : product.getProductImages()) {
                productImageService.build(productImage, session.getAttribute(IMAGE_TYPE).toString());
            }
            Collections.sort(product.getProductImages());
            if (product.getImage() == null && product.getThumbnail() != null) {
                product.setImage(product.getThumbnail());
            }

            for (ParameterGroup parameterGroup : product.getProductCategory().getParameterGroups()) {
                for (Parameter parameter : parameterGroup.getParameters()) {
                    String parameterValue = request.getParameter("parameter_" + parameter.getId());
                    if (StringUtils.isNotEmpty(parameterValue)) {
                        product.getParameterValue().put(parameter, parameterValue);
                    } else {
                        product.getParameterValue().remove(parameter);
                    }
                }
            }

            for (Attribute attribute : product.getProductCategory().getAttributes()) {
                String[] attributeValues = request.getParameterValues("attribute_" + attribute.getId());
                String attributeValue = "";
                if (attributeValues != null) {
                    for (int i = 0; i < attributeValues.length; i++) {
                        attributeValue = attributeValue + "," + attributeValues[i];
                    }
                }
                if (StringUtils.isNotEmpty(attributeValue)) {
                    product.setAttributeValue(attribute, attributeValue);
                } else {
                    product.setAttributeValue(attribute, null);
                }
            }
            product.setIsMarketable(true);
            product.setIsTop(false);
            if (!isValid(product)) {
                return ERROR_VIEW;
            }
            Goods goods = pProduct.getGoods();

            //排序copy
            List<Product> lists = pProduct.getSiblings();
            Iterator<Product> it = lists.iterator();
            while (it.hasNext()) {
                Product p = it.next();
                p.setOrder(product.getOrder());
                productService.update(p);
            }

            List<Product> products = new ArrayList<Product>();
            if (specificationIds != null && specificationIds.length > 0) {
                for (int i = 0; i < specificationIds.length; i++) {
                    Specification specification = specificationService.find(specificationIds[i]);
                    String[] specificationValueIds = request.getParameterValues("specification_" + specification.getId());
                    if (specificationValueIds != null && specificationValueIds.length > 0) {
                        for (int j = 0; j < specificationValueIds.length; j++) {
                            if (i == 0) {
                                if (j == 0) {
                                    BeanUtils.copyProperties(product, pProduct, "merchant", "id", "createDate", "modifyDate", "allocatedStock", "hits", "weekHits", "monthHits",
                                            "weekSales", "monthSales", "weekHitsDate", "monthHitsDate", "weekSalesDate", "monthSalesDate", "goods", "reviews", "consultations",
                                            "favoriteMembers", "specifications", "specificationValues", "promotions", "cartItems", "orderItems", "giftItems", "productNotifies", "sales");
                                    pProduct.setSpecifications(new HashSet<Specification>());
                                    pProduct.setSpecificationValues(new HashSet<SpecificationValue>());
                                    products.add(pProduct);
                                } else {
                                    if (specificationProductIds != null && j < specificationProductIds.length) {
                                        Product specificationProduct = productService.find(specificationProductIds[j]);
                                        if (specificationProduct == null || (specificationProduct.getGoods() != null && !specificationProduct.getGoods().equals(goods))) {
                                            return ERROR_VIEW;
                                        }
                                        specificationProduct.setSpecifications(new HashSet<Specification>());
                                        specificationProduct.setSpecificationValues(new HashSet<SpecificationValue>());
                                        products.add(specificationProduct);
                                    } else {
                                        Product specificationProduct = new Product();
                                        BeanUtils.copyProperties(product, specificationProduct);
                                        specificationProduct.setId(null);
                                        specificationProduct.setCreateDate(null);
                                        specificationProduct.setModifyDate(null);
                                        specificationProduct.setSn(null);
                                        specificationProduct.setAllocatedStock(0);
                                        specificationProduct.setHits(0L);
                                        specificationProduct.setWeekHits(0L);
                                        specificationProduct.setMonthHits(0L);
                                        specificationProduct.setSales(0L);
                                        specificationProduct.setWeekSales(0L);
                                        specificationProduct.setMonthSales(0L);
                                        specificationProduct.setWeekHitsDate(new Date());
                                        specificationProduct.setMonthHitsDate(new Date());
                                        specificationProduct.setWeekSalesDate(new Date());
                                        specificationProduct.setMonthSalesDate(new Date());
                                        specificationProduct.setGoods(goods);
                                        specificationProduct.setReviews(null);
                                        specificationProduct.setConsultations(null);
                                        specificationProduct.setFavoriteMembers(null);
                                        specificationProduct.setSpecifications(new HashSet<Specification>());
                                        specificationProduct.setSpecificationValues(new HashSet<SpecificationValue>());
                                        specificationProduct.setPromotions(null);
                                        specificationProduct.setCartItems(null);
                                        specificationProduct.setOrderItems(null);
                                        specificationProduct.setGiftItems(null);
                                        specificationProduct.setProductNotifies(null);
                                        products.add(specificationProduct);
                                    }
                                }
                            }
                            Product specificationProduct = products.get(j);
                            SpecificationValue specificationValue = specificationValueService.find(Long.valueOf(specificationValueIds[j]));
                            specificationProduct.getSpecifications().add(specification);
                            specificationProduct.getSpecificationValues().add(specificationValue);
                        }
                    }
                }
            } else {
                product.setSpecifications(null);
                product.setSpecificationValues(null);
                BeanUtils.copyProperties(product, pProduct, "merchant", "id", "createDate", "modifyDate", "allocatedStock", "hits", "weekHits", "monthHits", "weekSales", "monthSales",
                        "weekHitsDate", "monthHitsDate", "weekSalesDate", "monthSalesDate", "goods", "reviews", "consultations", "favoriteMembers", "promotions", "cartItems",
                        "orderItems", "giftItems", "productNotifies", "sales");
                products.add(pProduct);
            }
            goods.getProducts().clear();
            goods.getProducts().addAll(products);
            goodsService.update(goods);
            addFlashMessage(redirectAttributes, SUCCESS_MESSAGE);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:list.htm";
    }

    /**
     * 列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Long productCategoryId, Long brandId, Long promotionId, Long tagId, Boolean isMarketable, Boolean isList, Boolean isTop,
                       Boolean isOutOfStock, Boolean isStockAlert, Pageable pageable, ModelMap model) {
        ProductCategory productCategory = productCategoryService.find(productCategoryId);
        Brand brand = brandService.find(brandId);
        Promotion promotion = promotionService.find(promotionId);
        List<Tag> tags = tagService.findList(tagId);
        model.addAttribute("productCategoryTree", productCategoryService.findTree());
        model.addAttribute("brands", brandService.findAll());
        model.addAttribute("promotions", promotionService.findAll());
        model.addAttribute("tags", tagService.findList(Tag.Type.product));
        model.addAttribute("productCategoryId", productCategoryId);
        model.addAttribute("brandId", brandId);
        model.addAttribute("promotionId", promotionId);
        model.addAttribute("tagId", tagId);
        model.addAttribute("isMarketable", isMarketable);
        model.addAttribute("isList", isList);
        model.addAttribute("isTop", isTop);
        model.addAttribute("isOutOfStock", isOutOfStock);
        model.addAttribute("isStockAlert", isStockAlert);
        model.addAttribute("page", productService.findPageGroup(productCategory, brand, promotion, tags, null, null, null, isMarketable, isList, isTop, isOutOfStock,
                isStockAlert, null, pageable));
        return "/admin/product/list";
    }

    /**
     * 删除
     */
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public
    @ResponseBody
    com.hboxs.asl.Message delete(Long[] ids) {
        productService.delete(ids);
        return SUCCESS_MESSAGE;
    }

    /**
     * 计算默认积分
     *
     * @param price 价格
     */
    private BigDecimal calculateDefaultPoint(BigDecimal price) {
        return price;
    }


}